﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Cuckoo.TaskSchedule
{
	public class FixedTimer : IFixedTimer
	{
		/// <summary>
		/// 计时事件
		/// </summary>
		public event SecondTriggerHandle SecondTrigger;

		/// <summary>
		/// 触发计时事件
		/// </summary>
		public void OnSecondTrigger()
		{
            //如果预定时间和当前时间不相等则不执行任务
            if (nRunHour != DateTime.Now.Hour || nRunMinute != DateTime.Now.Minute || nRunSecond != DateTime.Now.Second)
            {
                return;
            }
            //判断日期值是否等于当前日期，如果等于则执行任务
            switch (FixedType)
            {
                case FixedType.FIXED_ERROR: throw new ExpressionException("表达式格式错误！");
                case FixedType.EVERYDAY_RUN:
                    {
                        SecondTrigger();
                    }
                    break;
                case FixedType.FIXEDYEAR_EVERYDAY_RUN:
                    {
                        if (nRunYear == DateTime.Now.Year)
                        {
                            SecondTrigger();
                        }
                    }
                    break;
                case FixedType.FIXMONTH_EVERYDAY_RUN:
                    {
                        if (nRunMonth == DateTime.Now.Month)
                        {
                            SecondTrigger();
                        }
                    }
                    break;
                case FixedType.FIXEDYEAR_FIXEDMONTH_EVERYDAY_RUN:
                    {
                        if (nRunYear == DateTime.Now.Year && nRunMonth == DateTime.Now.Month)
                        {
                            SecondTrigger();
                        }
                    }
                    break;
                case FixedType.EVERYMONTH_FIXEDDAY_RUN:
                    {
                        if (nRunDate == DateTime.Now.Day)
                        {
                            SecondTrigger();
                        }
                    }
                    break;
                case FixedType.FIXEDYEAR_EVERYMONTH_FIXEDDAY_RUN:
                    {
                        if (nRunYear == DateTime.Now.Year && nRunDate == DateTime.Now.Day)
                        {
                            SecondTrigger();
                        }
                    }
                    break;
                case FixedType.FIXEDYEAR_FIXEDDAY_RUN:
                    {
                        if (nRunYear == DateTime.Now.Year)
                        {
                            DateTime time = new DateTime(nRunYear, 1, 1);
                            if (nRunDate == ((DateTime.Now - time).TotalDays + 1))
                            {
                                SecondTrigger();
                            }
                        }
                    }
                    break;
                case FixedType.FIXEDYEAR_FIXEDMONTH_FIXEDDAY_RUN:
                    {
                        if (nRunYear == DateTime.Now.Year && nRunMonth == DateTime.Now.Month && nRunDate == DateTime.Now.Day)
                        {
                            SecondTrigger();
                        }
                    }
                    break;
                case FixedType.EVERYYEAR_EVERYMONTH_FIXEDWEEKDAY_RUN:
                    {
                        if (nRunDay == ((int)DateTime.Now.DayOfWeek == 0 ? 7 : (int)DateTime.Now.DayOfWeek))
                        {
                            int totalday = TaskStrategyHelper.GetTotalByNumAndDay(DateTime.Now.Year, DateTime.Now.Month,
                            nRunNum, nRunDay);
                            DateTime time = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
                            DateTime time1 = time.AddDays(totalday - 1);
                            if (time.Month == time1.Month)
                            {
                                if (totalday == DateTime.Now.Day)
                                {
                                    SecondTrigger();
                                }
                            }
                        }
                    }
                    break;
                case FixedType.EVERYYEAR_FIXEDMONTH_FIXEDWEEKDAY_RUN:
                    {
                        if (nRunMonth == DateTime.Now.Month && nRunDay == ((int)DateTime.Now.DayOfWeek == 0 ? 7 : (int)DateTime.Now.DayOfWeek))
                        {
                            int totalday = TaskStrategyHelper.GetTotalByNumAndDay(DateTime.Now.Year, nRunMonth,
                            nRunNum, nRunDay);
                            DateTime time = new DateTime(DateTime.Now.Year, nRunMonth, 1);
                            DateTime time1 = time.AddDays(totalday - 1);
                            if (time.Month == time1.Month)
                            {
                                if (totalday == DateTime.Now.Day)
                                {
                                    SecondTrigger();
                                }
                            }
                        }
                    }
                    break;
                case FixedType.FIXEDYEAR_EVERYMONTH_FIXEDWEEKDAY_RUN:
                    {
                        if (nRunYear == DateTime.Now.Year && nRunDay == ((int)DateTime.Now.DayOfWeek == 0 ? 7 : (int)DateTime.Now.DayOfWeek))
                        {
                            int totalday = TaskStrategyHelper.GetTotalByNumAndDay(nRunYear, DateTime.Now.Month,
                            nRunNum, nRunDay);
                            DateTime time = new DateTime(nRunYear, DateTime.Now.Month, 1);
                            DateTime time1 = time.AddDays(totalday - 1);
                            if (time.Month == time1.Month)
                            {
                                if (totalday == DateTime.Now.Day)
                                {
                                    SecondTrigger();
                                }
                            }
                        }
                    }
                    break;
                case FixedType.FIXEDYEAR_FIXEDMONTH_FIXEDWEEKDAY_RUN:
                    {
                        if (nRunYear == DateTime.Now.Year && nRunMonth == DateTime.Now.Month && nRunDay == ((int)DateTime.Now.DayOfWeek == 0 ? 7 : (int)DateTime.Now.DayOfWeek))
                        {
                            int totalday = TaskStrategyHelper.GetTotalByNumAndDay(nRunYear, nRunMonth,
                            nRunNum, nRunDay);
                            DateTime time = new DateTime(nRunYear, nRunMonth, 1);
                            DateTime time1 = time.AddDays(totalday - 1);
                            if (time.Month == time1.Month)
                            {
                                if (totalday == DateTime.Now.Day)
                                {
                                    SecondTrigger();
                                }
                            }
                        }
                    }
                    break;
                case FixedType.EVERYYEAR_FIXEDWEEKDAY_RUN:
                    {
                        if (nRunDay == ((int)DateTime.Now.DayOfWeek == 0 ? 7 : (int)DateTime.Now.DayOfWeek))
                        {
                            int totalday = TaskStrategyHelper.GetTotalByNumAndDay(DateTime.Now.Year, 1,
                            nRunNum, nRunDay);
                            DateTime time = new DateTime(DateTime.Now.Year, 1, 1);
                            DateTime time1 = time.AddDays(totalday - 1);
                            if (time.Year == time1.Year)
                            {
                                SecondTrigger();
                            }
                        }
                    }
                    break;
                case FixedType.FIXEDYEAR_FIXEDWEEKDAY_RUN: 
                    {
                        if (nRunYear == DateTime.Now.Year && nRunDay == ((int)DateTime.Now.DayOfWeek == 0 ? 7 : (int)DateTime.Now.DayOfWeek))
                        {
                            int totalday = TaskStrategyHelper.GetTotalByNumAndDay(nRunYear, 1,
                            nRunNum, nRunDay);
                            DateTime time = new DateTime(nRunYear, 1, 1);
                            DateTime time1 = time.AddDays(totalday - 1);
                            if (time.Year == time1.Year)
                            {
                                SecondTrigger();
                            }
                        }
                    }
                    break;
                case FixedType.EVERYYEAR_EVERYMONTH_EVERYWEEKDAY_RUN:
                    {
                        if (nRunDay == ((int)DateTime.Now.DayOfWeek == 0 ? 7 : (int)DateTime.Now.DayOfWeek))
                        {
                            SecondTrigger();
                        }
                    }
                    break;
                case FixedType.EVERYYEAR_FIXEDMONTH_EVERYWEEKDAY_RUN: 
                    {
                        if (nRunMonth == DateTime.Now.Month && nRunDay == ((int)DateTime.Now.DayOfWeek == 0 ? 7 : (int)DateTime.Now.DayOfWeek))
                        {
                            SecondTrigger();
                        }
                    }
                    break;
                case FixedType.FIXEDYEAR_EVERYMONTH_EVERYWEEKDAY_RUN: 
                    {
                        if (nRunYear == DateTime.Now.Year && nRunDay == ((int)DateTime.Now.DayOfWeek == 0 ? 7 : (int)DateTime.Now.DayOfWeek))
                        {
                            SecondTrigger();
                        }
                    }
                    break;
                case FixedType.FIXEDYEAR_FIXEDMONTH_EVERYWEEKDAY_RUN: 
                    {
                        if (nRunYear == DateTime.Now.Year && nRunMonth == DateTime.Now.Month && nRunDay == ((int)DateTime.Now.DayOfWeek == 0 ? 7 : (int)DateTime.Now.DayOfWeek))
                        {
                            SecondTrigger();
                        }
                    }
                    break;
                case FixedType.EVERYYEAR_EVERYWEEKDAY_RUN:
                    {
                        if (nRunDay == ((int)DateTime.Now.DayOfWeek == 0 ? 7 : (int)DateTime.Now.DayOfWeek))
                        {
                            SecondTrigger();
                        }
                    }
                    break;
                case FixedType.FIXEDYEAR_EVERYWEEKDAY_RUN: 
                    {
                        if (nRunYear == DateTime.Now.Year && nRunDay == ((int)DateTime.Now.DayOfWeek == 0 ? 7 : (int)DateTime.Now.DayOfWeek))
                        {
                            SecondTrigger();
                        }
                    }
                    break;
            }
		}

		/// <summary>
		/// 开始计时工作
		/// </summary>
		public void Work()
		{
			
			
		}

        /// <summary>
        /// 已运行时间
        /// </summary>
        public long TotalSecond { get; set; }

        /// <summary>
        /// 绑定到计时器上的任务
        /// </summary>
        public ITask Task { get; set; }

        /// <summary>
        /// 预定运行时间，年份
        /// </summary>
        public int nRunYear { get; set; }

        /// <summary>
        /// 预定运行时间，月份
        /// </summary>
        public int nRunMonth { get; set; }

        /// <summary>
        /// 预定运行时间，天
        /// </summary>
        public int nRunDate { get; set; }

		/// <summary>
		/// 预定运行时间，和nRunDay共用，表示第nRunDay个星期nRunDay
		/// </summary>
		public int nRunNum { get; set; }

		/// <summary>
		/// 预定运行时间，表示星期nRunDay
		/// </summary>
		public int nRunDay { get; set; }

        /// <summary>
        /// 预定运行时间，小时
        /// </summary>
        public int nRunHour { get; set; }

        /// <summary>
        /// 预定运行时间，分钟
        /// </summary>
        public int nRunMinute { get; set; }

        /// <summary>
        /// 预定运行时间，秒
        /// </summary>
        public int nRunSecond { get; set; }

        /// <summary>
        /// 间隔时间
        /// </summary>
        public long Interval { get; set; }

        /// <summary>
        /// 执行次数
        /// </summary>
        public int nMaxCount { get; set; }

		/// <summary>
		/// 时间表达式类型
		/// </summary>
		public FixedType FixedType { get; set; }
	}
}
